package com.study.jdk.j8;

import lombok.Getter;
import lombok.Setter;
import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @program: juc-study
 * @author: jzhou
 * @date: 2022-08-29 16:40
 * @version: 1.0
 * @description: 流
 **/
public class StreamDemo {
	List<Person> personList ;
	@Before
	public void init(){
		personList = new ArrayList<>();
		personList.add(new Person("Tom", 8900, 23,"male", "New York"));
		personList.add(new Person("Jack", 7000, 25,"male", "Washington"));
		personList.add(new Person("Lily", 7800, 22,"female", "Washington"));
		personList.add(new Person("Anni", 8200, 18,"female", "New York"));
		personList.add(new Person("Owen", 9500, 26,"male", "New York"));
		personList.add(new Person("Alisa", 7900, 30,"female", "New York"));
	}

	// 流创建
	@Test
	public void test1() {
		/* 1、通过 java.util.Collection.stream() 方法用集合创建流 */
		List<String> list = Arrays.asList("a", "b", "c");
		// 创建一个顺序流
		Stream<String> stream = list.stream();
		// 创建一个并行流
		Stream<String> parallelStream = list.parallelStream();
		/* 2、使用java.util.Arrays.stream(T[] array)方法用数组创建流 */
		int[] array = {1, 3, 5, 6, 8};
		IntStream intStream = Arrays.stream(array);
		/* 3、使用Stream的静态方法：of()、iterate()、generate() */
		Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);
		Optional<Integer> findFirst = stream1.parallel().filter(x -> x > 6).findFirst();

		Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
		stream2.forEach(System.out::println);

		Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
		stream3.forEach(System.out::println);
	}

	// 筛选 与 切片
	@Test
	public void test2(){
		String[] arr1 = { "a", "b", "c", "d" };
		String[] arr2 = { "d", "e", "f", "g" };

		Stream<String> stream1 = Stream.of(arr1);
		Stream<String> stream2 = Stream.of(arr2);
// concat:合并两个流 distinct：去重
		List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
// limit：限制从流中获得前n个数据
		List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
// skip：跳过前n个数据 正好和
		List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(10).collect(Collectors.toList());

		System.out.println("流合并：" + newList);
		System.out.println("limit：" + collect);
		System.out.println("skip：" + collect2);
	}

	// 映射
	@Test
	public void test3(){
		String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
		List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
		System.out.println("每个元素大写：" + strList);

		List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);
		List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());
		System.out.println("每个元素+3：" + intListNew);

		// 不改变原来员工集合的方式
		List<Person> personListNew = personList.stream().map(person -> {
			Person personNew = new Person(person.getName(), 0, 0, null, null);
			personNew.setSalary(person.getSalary() + 10000);
			return personNew;
		}).collect(Collectors.toList());
		System.out.println("一次改动前：" + personList.get(0).getName() + "-->" + personList.get(0).getSalary());
		System.out.println("一次改动后：" + personListNew.get(0).getName() + "-->" + personListNew.get(0).getSalary());

// 改变原来员工集合的方式
		List<Person> personListNew2 = personList.stream().map(person -> {
			person.setSalary(person.getSalary() + 10000);
			return person;
		}).collect(Collectors.toList());
		System.out.println("二次改动前：" + personList.get(0).getName() + "-->" + personListNew.get(0).getSalary());
		System.out.println("二次改动后：" + personListNew2.get(0).getName() + "-->" + personListNew.get(0).getSalary());

		List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
		List<String> listNew = list.stream().flatMap(s -> {
			// 将每个元素转换成一个stream
			String[] split = s.split(",");
			Stream<String> s2 = Arrays.stream(split);
			return s2;
		}).collect(Collectors.toList());

		System.out.println("处理前的集合：" + list);
		System.out.println("处理后的集合：" + listNew);
	}

	// 排序
	@Test
	public void test4(){
		// 按工资升序排序（自然排序）
		List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
				.collect(Collectors.toList());
// 按工资倒序排序
		List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
				.map(Person::getName).collect(Collectors.toList());
// 先按工资再按年龄升序排序
		List<String> newList3 = personList.stream()
				.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
				.collect(Collectors.toList());
	}



}


@Getter
@Setter
class Person {
	private String name; // 姓名
	private int salary; // 薪资
	private int age; // 年龄
	private String sex; //性别
	private String area; // 地区

	// 构造方法
	public Person(String name, int salary, int age,String sex,String area) {
		this.name = name;
		this.salary = salary;
		this.age = age;
		this.sex = sex;
		this.area = area;
	}
}
